package com.fy.service.service.impl;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.fy.common.constant.RedisKeyConstant;
import com.fy.common.dto.BaseIdDto;
import com.fy.common.dto.UserDetailQueryDto;
import com.fy.common.dto.UserFriendSettingDto;
import com.fy.common.dto.UserLabelSetDto;
import com.fy.common.entity.SkImChatSession;
import com.fy.common.entity.SkImUserFriends;
import com.fy.common.enums.SkImCommonStatusEnum;
import com.fy.common.util.ImUtil;
import com.fy.common.util.TokenUtil;
import com.fy.common.vo.UserFriendListVo;
import com.fy.common.vo.UserInfoVo;
import com.fy.dao.mapper.SkImUserFriendsMapper;
import com.fy.framework.common.model.R;
import com.fy.framework.component.config.LocaleMessage;
import com.fy.framework.component.config.RedissonComponet;
import com.fy.service.service.SkImChatSessionService;
import com.fy.service.service.SkImUserFriendsService;
import com.fy.service.service.SkImUserInfoService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RMapCache;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;
import java.util.Objects;

/**
 * @author zhshuo
 * @date 2021/12/02 16:43
 **/
@Slf4j
@Service
public class SkImUserFriendsServiceImpl extends ServiceImpl<SkImUserFriendsMapper, SkImUserFriends>
    implements SkImUserFriendsService {

    LocaleMessage localeMessage;

    RedissonComponet redissonComponet;

    SkImUserInfoService userInfoService;

    SkImChatSessionService chatSessionService;

    @Override
    public Integer userLabelSet(UserLabelSetDto userLabelSetDto) {
        return baseMapper.userLabelSet(userLabelSetDto);
    }

    @Override
    public R<?> list(Long userId) {
        List<UserFriendListVo> listVoList = baseMapper.list(userId);
        return R.success(listVoList);
    }

    @Override
    public R<?> setting(UserFriendSettingDto userFriendSettingDto) {
        boolean update = update(
            new SkImUserFriends()
                .setUserLabelId(userFriendSettingDto.getLabelId())
                .setUserNickRemark(userFriendSettingDto.getUserNickRemark()),
            new EntityWrapper<SkImUserFriends>().eq("sk_im_user_id", TokenUtil.getUserId()).eq("target_user_id",
                userFriendSettingDto.getTargetUserId()));

        if(Objects.nonNull(userFriendSettingDto.getMute()) || Objects.nonNull(userFriendSettingDto.getTop())){
            SkImChatSession chatSession = null;
            String chatSessionKey = ImUtil.chatSessionIdGenFriend(TokenUtil.getUserId(), userFriendSettingDto.getTargetUserId());
            RMapCache<String, Object> mapCache = redissonComponet.getMap(RedisKeyConstant.USER_CHAT_SESSION + TokenUtil.getUserId());
            if(mapCache.containsKey(chatSessionKey)){
                chatSession = (SkImChatSession)mapCache.get(chatSessionKey);
                if(Objects.nonNull(userFriendSettingDto.getMute())){
                    chatSession.setIsMute(userFriendSettingDto.getMute());
                }
                if(Objects.nonNull(userFriendSettingDto.getTop())){
                    chatSession.setIsTop(userFriendSettingDto.getMute());
                    if(userFriendSettingDto.getTop().equals(Boolean.TRUE)){
                        chatSession.setTopTime(new Date());
                    }else{
                        chatSession.setTopTime(null);
                    }
                }
                mapCache.put(chatSessionKey,chatSession);
            }
            chatSessionService.topOrMuteSet(chatSession);
        }
        return update ? R.success(localeMessage.getMessage("im.common.success"))
            : R.failedAlter(localeMessage.getMessage("im.common.failedful"));
    }

    @Override
    public R<UserInfoVo> detail(UserDetailQueryDto detailQueryDto) {
        UserInfoVo vo = baseMapper.userFriendDetail(detailQueryDto.getTargetUserId(),TokenUtil.getUserId());
        String sessionKey = ImUtil.chatSessionIdGenFriend(TokenUtil.getUserId(), detailQueryDto.getTargetUserId());
        RMapCache<String, Object> map = redissonComponet.getMap(RedisKeyConstant.USER_CHAT_SESSION + detailQueryDto.getTargetUserId());
        SkImChatSession session;
        if(map.containsKey(sessionKey)){
            session = (SkImChatSession)map.get(sessionKey);
        }else{
            session = chatSessionService.selectOne(new EntityWrapper<SkImChatSession>().eq("sk_im_user_id", TokenUtil.getUserId())
                    .eq("target_id", detailQueryDto.getTargetUserId()));
        }
        vo.setChatSession(session);
        return R.success(vo);
    }

    @Override
    public R<?> del(BaseIdDto baseIdDto) {
        Long mainUserId = TokenUtil.getUserId();
        Long delUserId = baseIdDto.getId();

        SkImUserFriends userFriends = selectOne(new EntityWrapper<SkImUserFriends>().eq("sk_im_user_id", mainUserId).eq("target_user_id", delUserId));
        if(Objects.isNull(userFriends) || userFriends.getStatus().equals(SkImCommonStatusEnum.DELETED.getStatus())){
            return R.failedAlter(localeMessage.getMessage("im.common.parameterError"));
        }
        update(new SkImUserFriends().setStatus(SkImCommonStatusEnum.DELETED.getStatus()),new EntityWrapper<SkImUserFriends>()
                .eq("sk_im_user_id", mainUserId).eq("target_user_id", delUserId));
        update(new SkImUserFriends().setStatus(SkImCommonStatusEnum.DELETED.getStatus()),new EntityWrapper<SkImUserFriends>()
                .eq("sk_im_user_id", delUserId).eq("target_user_id", mainUserId));
        chatSessionService.update(new SkImChatSession().setStatus(SkImCommonStatusEnum.DELETED.getStatus()),new EntityWrapper<SkImChatSession>()
                .eq("session_id",ImUtil.chatSessionIdGenFriend(mainUserId,delUserId)));
        chatSessionService.update(new SkImChatSession().setStatus(SkImCommonStatusEnum.DELETED.getStatus()),new EntityWrapper<SkImChatSession>()
                .eq("session_id",ImUtil.chatSessionIdGenFriend(delUserId,mainUserId)));
        RMapCache<String, Object> mainUserChatSession = redissonComponet.getMap(RedisKeyConstant.USER_CHAT_SESSION + mainUserId);
        mainUserChatSession.remove(ImUtil.chatSessionIdGenFriend(mainUserId,delUserId));
        RMapCache<String, Object> depUserChatSession = redissonComponet.getMap(RedisKeyConstant.USER_CHAT_SESSION + delUserId);
        depUserChatSession.remove(ImUtil.chatSessionIdGenFriend(delUserId,mainUserId));
        return R.success(localeMessage.getMessage("im.common.successful"));
    }

    @Autowired
    public void setLocaleMessage(LocaleMessage localeMessage) {
        this.localeMessage = localeMessage;
    }

    @Autowired
    public void setRedissonComponet(RedissonComponet redissonComponet) {
        this.redissonComponet = redissonComponet;
    }

    @Autowired
    public void setUserInfoService(SkImUserInfoService userInfoService) {
        this.userInfoService = userInfoService;
    }

    @Autowired
    public void setChatSessionService(SkImChatSessionService chatSessionService) {
        this.chatSessionService = chatSessionService;
    }
}
